
#include "aky_program/aky_com_include.h"

s_mem_index_t g_s_mem_index = {0};
e_aky_flash_t g_e_flash_err = 0;
s_mem_t g_s_mem = {0};
s_mem_t g_s_mem_send = {0};
s_set_t g_s_set = {0};
s_general_save_t g_s_general_save = {0};

uint8_t *flash_buf; //

e_user_t g_e_user = USER_1;



void aky_flash_init(void)
{
	Flash_Param_at_xMHz(150);

    flash_buf = lv_mem_alloc(FLASH_BUF_SIZE);
    memset((uint8_t *)flash_buf,0x00,FLASH_BUF_SIZE);
    if (flash_buf != NULL)
    {
        printf("flash_buf lv_mem_alloc  %ld  byte\n",(FLASH_BUF_SIZE));
    }

    printf("sizeof(s_mem_index_t) = %d\n",sizeof(s_mem_index_t));
    printf("sizeof(s_mem_t) = %d\n",sizeof(s_mem_t));

    printf("MAX_MEM_ADDR_SIZE = %d\n",(uint32_t)MAX_MEM_ADDR_SIZE);
    printf("aky_flash_start_addr = 0x%x\n",(uint32_t)aky_flash_start_addr);
    printf("user_all_back_addr = 0x%x\n",(uint32_t)user_all_back_addr);
    printf("user_1_addr  = 0x%x\n",(uint32_t)user_1_addr );
    printf("user_2_addr  = 0x%x\n",(uint32_t)user_2_addr );
    printf("user_3_addr  = 0x%x\n",(uint32_t)user_3_addr );


    printf("flash_end_addr = 0x%x\n",(uint32_t)flash_end_addr);
    

    printf("user_set_addr = 0x%x\n",(uint32_t)user_set_addr);
    printf("user_set_back_addr = 0x%x\n",(uint32_t)user_set_back_addr);
    // printf("general_save_addr = 0x%x\n",(uint32_t)general_save_addr);

    g_s_set = get_flash_set_data();
    g_e_flash_err = check_mem_bank(g_e_user);

    printf("aky_flash_init\n");
    #if 22 && (AKY_DEBUG_ENABLE == 1)
    // flash_test_2();
        // clr_mem_bank(USER_1);
        g_s_mem_index = flash_get_mem_index_data(USER_1,&g_e_flash_err,MAIN_ADDR);
        strcpy(( char *)g_s_mem_index.user_name_buf,(const char *)"李璐");
        g_s_mem_index.gender = WOMAN;
        g_s_mem_index.flag_is_user_info_valid = 1;
         strcpy(( char *)g_s_mem_index.age_buf,(const char *)"33");
       strcpy(( char *)g_s_mem_index.phone_num_buf,(const char *)"12345678901");
        flash_save_mem_index_data(g_s_mem_index,USER_1,MAIN_ADDR); //
        // if (g_s_mem_index.cur_mem_index == 0)
        // {
        //     for (uint8_t i = 0; i < 7; i++)
        //     {
        //     memset((uint8_t *)&g_s_mem,0,sizeof(s_mem_t));
        //     g_s_mem.s_time = g_s_time;
        //         g_s_mem.s_time.secon += i;
        //         g_s_mem.s_left_bp.sys = i;
        //         g_s_mem.s_left_bp.dia = 10+i;
        //         g_s_mem.s_left_bp.pul = 20+i;
        //         g_s_mem.s_right_bp.sys = 20+i;
        //         g_s_mem.s_right_bp.dia = 10+i;
        //         g_s_mem.s_right_bp.pul = i;
        //         g_s_mem.s_train_time.min = i;
        //         g_s_mem.s_train_time.secon = 10+i;
        //         insert_one_mem(g_s_mem,USER_1);
        //         // g_s_mem = flash_get_mem_data(USER_1,g_s_mem_index.cur_mem_index,&g_e_flash_err,MAIN_ADDR);
        //         AKY_ASM_NOP();
        //     }
        // }        
#endif

}

// 写入多个字节到flash
// addr 写入的开始地址
// p_u8_buf 需要写入的数据buff缓存
// num 写入字节数 最小写入16字节
// return 错误码  AKY_FLASH_OK  AKY_FLASH_ERR
e_aky_flash_t aky_flash_write_bytes(uint32_t addr, uint8_t *p_u8_buf, uint16_t num)
{
    e_aky_flash_t res = AKY_FLASH_OK;
    uint32_t status = FLASH_RES_OK;
    
    uint32_t *p_u32_buf;
    uint32_t addr_cnt = 0;
    uint32_t addr_temp = 0;
    uint8_t u8_temp = 0;
    uint32_t u32_temp = 0;


    if ((addr < aky_flash_start_addr || addr > flash_end_addr))
    {
        return AKY_FLASH_ERR; //
    }

    if (num % 16)
    {
        return AKY_FLASH_ERR; // 必须为16的倍数
    }

    p_u32_buf = (uint32_t *)p_u8_buf;
	__disable_irq();

    for (addr_cnt = addr; addr_cnt < (addr + num); addr_cnt += (64*4))
    {
        if (addr_cnt >= flash_end_addr)
        {
            break;
        }
#if (AKY_FLASH_DEBUG_ENABLE == 1)
        status = FLASH_Write(addr_cnt, (uint32_t *)p_u32_buf, 64);

#else
        SFC_Write(addr_cnt, (uint32_t *)p_u32_buf, 64);
#endif

        p_u32_buf+=64;
        if (status != FLASH_RES_OK)
        {
            res = AKY_FLASH_ERR;
        }
        else
        {
        }

    }

	__enable_irq();

    return res;
}


// 从flash读取多个字节到buff
// addr 读取的开始地址
// p_u8_buf 读取的数据buff缓存
// num 读取的字节数
// return 错误码  AKY_FLASH_OK  AKY_FLASH_ERR
e_aky_flash_t aky_flash_read_bytes(uint32_t addr, uint8_t *p_u8_buf, uint16_t num)
{
    e_aky_flash_t res = AKY_FLASH_OK;
    uint32_t addr_cnt = 0;
    uint32_t addr_temp = 0;
    uint8_t u8_temp_buf[4] = {0};
    uint16_t index_cnt = 0;
    uint32_t *p_u32_buf;

    if ((addr < aky_flash_start_addr || addr > flash_end_addr))
    {
        return AKY_FLASH_ERR; //
    }
	__disable_irq();

#if (AKY_FLASH_DEBUG_ENABLE == 1)
    for (addr_cnt = addr; addr_cnt < (addr + num); addr_cnt++)
    {
        if (addr_cnt >= flash_end_addr)
        {
            break;
        }
        {
            *p_u8_buf++ = *(__IO uint8_t*) addr_cnt;
        }
    }
#else
    index_cnt = 0;
    for (addr_cnt = addr; addr_cnt < (addr + num); addr_cnt+=1)
    {
        if (addr_cnt >= flash_end_addr)
        {
            break;
        }
        if (index_cnt == 0)
        {
            SFC_Read(addr_cnt, (uint32_t*)u8_temp_buf, 1);
        }

        *p_u8_buf++ = u8_temp_buf[index_cnt];

        index_cnt++;
        if (index_cnt > 3)
        {
            index_cnt = 0;
        }
    }

#endif
    __enable_irq();



    return res;
}

// 擦除多个扇区
// addr 擦除的开始地址
//  pages 要擦除的扇区数量
// return 错误码  AKY_FLASH_OK  AKY_FLASH_ERR
e_aky_flash_t aky_flash_erase_pages(uint32_t addr, uint16_t pages)
{
    e_aky_flash_t res = AKY_FLASH_OK;
    uint32_t status = FLASH_RES_OK;
    uint32_t page_temp = 0;
    uint16_t i;

    if ((addr < aky_flash_start_addr || addr > flash_end_addr))
    {
        return AKY_FLASH_ERR; //
        
    }

    addr = addr / AKY_ONE_SEC_SIZE;
    addr = addr * AKY_ONE_SEC_SIZE; // 对齐
	__disable_irq();

    for (i = 0; i < pages; i++)
    {
        if ((addr + (i * AKY_ONE_SEC_SIZE)) >= flash_end_addr)
        {
            break;
        }
#if (AKY_FLASH_DEBUG_ENABLE == 1)
        {
            status =  FLASH_Erase((addr + (i * AKY_ONE_SEC_SIZE)));
        }

#else
        SFC_Erase((addr + (i * AKY_ONE_SEC_SIZE)), 1);
#endif


        if (status != FLASH_RES_OK)
        {
            res = AKY_FLASH_ERR;
            break;
        }
        else
        {
            res = AKY_FLASH_OK;
        }
    }
    __enable_irq();

    return res;
}


// 默认下标值
s_mem_index_t get_default_mem_index_data(void)
{
    s_mem_index_t s_mem_index_res = {0};
    memset((uint8_t *)&s_mem_index_res,0x00,sizeof(s_mem_index_t));
    s_mem_index_res.cur_mem_index = 0;
    s_mem_index_res.mem_set = MAX_MEM_SIZE;
    s_mem_index_res.flag_mem_overwrite = 0;
    // s_mem_index_res.e_user = g_s_set.e_user;
    s_mem_index_res.e_user = g_e_user;
    s_mem_index_res.gender = MAN;

    return s_mem_index_res;
}

// 默认设定值
s_set_t get_default_set_data(void)
{
    s_set_t s_set_res = {0};

    s_set_res.voice_level = 3;
    s_set_res.bl_level = 3;
    s_set_res.flag_net_work = 1;

    s_set_res.fill_byte1 = 0x5a;//填充字节
    s_set_res.fill_byte2 = 0x5a;
    s_set_res.fill_byte3 = 0x5a;

    return s_set_res;
}

// 得出多个字节的校验和
// p_u8_buf 要进行计算的缓存
// num 字节数
// return 校验和
uint8_t get_bytes_checksum(uint8_t *p_u8_buf, uint16_t num)
{
    uint16_t i = 0;
    uint8_t res = 0;

    for (i = 0; i < num; i++)
    {
        res += *p_u8_buf++;
    }

    return res;
}

// 得出结构体到checksum中间字节数
// p_start_addr 结构体开始地址
// p_stop_addr 结构体checksum的地址
// return 字节数
uint16_t get_stru_checksum_offset_bytes(uint8_t *p_start_addr, uint8_t *p_stop_addr)
{
    uint16_t res = 0;
    res = p_stop_addr - p_start_addr;
    return res;
}

// 取用户flash地址
uint32_t get_user_addr(e_user_t e_user)
{
    uint32_t res = 0;

    if (e_user == USER_1)
    {
        res = user_1_addr;
    }
    else if (e_user == USER_2)
    {
        res = user_2_addr;
    }
    else if (e_user == USER_3)
    {
        res = user_3_addr;
    }
    else
    {
        res = flash_end_addr - AKY_ONE_SEC_SIZE;
        printf("get_user_addr err\n");
    }
    return res;
}

// 取用户备份flash地址
uint32_t get_user_back_addr(e_user_t e_user)
{
    uint32_t res = 0;
    res = user_all_back_addr;

    // if (e_user == USER_1)
    // {
    //     res = user_1_back_addr;
    // }
    // else if (e_user == USER_2)
    // {
    //     res = user_2_back_addr;
    // }
    // else if (e_user == USER_3)
    // {
    //     res = user_3_back_addr;
    // }
    // else
    // {
    // }
    return res;
}

// 保存下标
e_aky_flash_t flash_save_mem_index_data(s_mem_index_t s_mem_index, e_user_t e_user ,e_addr_t e_addr)
{
    uint16_t bytes = 0;
    e_aky_flash_t res = AKY_FLASH_OK;
    volatile uint32_t addr = 0;
    // uint32_t addr_back = 0;
    uint16_t i, j = 0;
    uint8_t *p_u8_buf;

    addr = get_user_addr(e_user); // 得出当前用户的地址
    if (e_addr == MAIN_ADDR)
    {
        addr = get_user_addr(e_user); // 得出当前用户的地址
    }
    else if (e_addr == BACK_ADDR)
    {
        addr = get_user_back_addr(e_user); // 
    }
    
    res = aky_flash_read_bytes(addr, (uint8_t *)flash_buf, FLASH_BUF_SIZE); // 将flash数据读到缓存
    if (res != AKY_FLASH_OK)
    {
        return res;
    }

    res = aky_flash_erase_pages(addr, 1); // 擦除
    if (res != AKY_FLASH_OK)
    {
        return res;
    }

    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_mem_index, (uint8_t *)&s_mem_index.check_sum);
    s_mem_index.check_sum = get_bytes_checksum((uint8_t *)&s_mem_index, bytes); // 计算校验和
    p_u8_buf = (uint8_t *)&s_mem_index;
    for (i = 0; i < sizeof(s_mem_index_t); i++) // 下标数据放入缓存
    {
        flash_buf[i] = p_u8_buf[i];
    }

    res = aky_flash_write_bytes(addr, (uint8_t *)flash_buf, AKY_ONE_SEC_SIZE); // 将缓存写回flash

    return res;
}


// 取flash的下标数据
s_mem_index_t flash_get_mem_index_data(e_user_t e_user, e_aky_flash_t *p_e_flash_err,e_addr_t e_addr)
{
    volatile s_mem_index_t s_mem_index_res = {0};
    uint16_t bytes = 0;
    uint32_t addr = 0;
    *p_e_flash_err = AKY_FLASH_OK;
    addr = get_user_addr(e_user);
    if (e_addr == MAIN_ADDR)
    {
        addr = get_user_addr(e_user); // 得出当前用户的地址
    }
    else if (e_addr == BACK_ADDR)
    {
        addr = get_user_back_addr(e_user); // 
    }

    *p_e_flash_err = aky_flash_read_bytes(addr, (uint8_t *)&s_mem_index_res, sizeof(s_mem_index_t));

    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_mem_index_res, (uint8_t *)&s_mem_index_res.check_sum);
    if (s_mem_index_res.check_sum != get_bytes_checksum((uint8_t *)&s_mem_index_res, bytes) || *p_e_flash_err == AKY_FLASH_ERR) // 校验出错
    {
        s_mem_index_res = get_default_mem_index_data(); // 读默认
    }
    else
    {

    }

    return s_mem_index_res;
}

// 保存记忆
e_aky_flash_t flash_save_mem_data(s_mem_t s_mem, e_user_t e_user, uint16_t index,e_addr_t e_addr)
{
    uint16_t bytes = 0;
    e_aky_flash_t res = AKY_FLASH_OK;
    uint32_t addr = 0;
    uint16_t i = 0;
    uint8_t *p_u8_buf;
    uint32_t addr_offset = 0;
    uint16_t index_offset = 0;

    if (index == 0 || index > MAX_MEM_SIZE)
    {
        return AKY_FLASH_ERR;
    }

    if (e_addr == MAIN_ADDR)
    {
        addr = get_user_addr(e_user); // 得出当前用户的地址
    }
    else if (e_addr == BACK_ADDR)
    {
        addr = get_user_back_addr(e_user); // 
    }

    addr_offset = ((index) * sizeof(s_mem_t)) + sizeof(s_mem_index_t);
    if (addr_offset % AKY_ONE_SEC_SIZE > (sizeof(s_mem_t) + sizeof(s_mem_index_t)))
    {
        addr_offset = (addr_offset / AKY_ONE_SEC_SIZE ) * AKY_ONE_SEC_SIZE;  // 需要偏移的地址数
    }
    else
    {
        addr_offset = (addr_offset / AKY_ONE_SEC_SIZE ) * AKY_ONE_SEC_SIZE;  // 需要偏移的地址数
        if (addr_offset >= AKY_ONE_SEC_SIZE)
        {
            addr_offset -= AKY_ONE_SEC_SIZE;
        }
    }

    addr = addr + addr_offset;

    index_offset = ((index - 1) * sizeof(s_mem_t)) + sizeof(s_mem_index_t); // 需要偏移的缓存下标数
    index_offset = index_offset - addr_offset;
	
    res = aky_flash_read_bytes(addr, (uint8_t *)flash_buf, FLASH_BUF_SIZE); // 读取数据到缓存
    if (res != AKY_FLASH_OK)
    {
        return res;
    }

    res = aky_flash_erase_pages(addr, FLASH_BUF_SIZE / AKY_ONE_SEC_SIZE);
    if (res != AKY_FLASH_OK)
    {
        return res;
    }


    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_mem, (uint8_t *)&s_mem.check_sum);
    s_mem.check_sum = get_bytes_checksum((uint8_t *)&s_mem, bytes);

    p_u8_buf = (uint8_t *)&s_mem; // 记忆数据放到缓存
    for (i = index_offset; i < index_offset + sizeof(s_mem); i++) //
    {
        flash_buf[i] = *p_u8_buf++;
    }

    res = aky_flash_write_bytes(addr, (uint8_t *)flash_buf, FLASH_BUF_SIZE); // 缓存写回flash

    return res;
}

// 取flash的记忆
s_mem_t flash_get_mem_data(e_user_t e_user, uint16_t index, e_aky_flash_t *p_e_flash_err,e_addr_t e_addr)
{
    volatile s_mem_t s_mem_res = {0};
    uint16_t bytes = 0;
    uint32_t addr = 0;
    uint32_t addr_offset = 0;

    *p_e_flash_err = AKY_FLASH_OK;

    if (index == 0 || index > MAX_MEM_SIZE)
    {
        *p_e_flash_err = AKY_FLASH_ERR;
        memset((uint8_t *)&s_mem_res, 0xff, sizeof(s_mem_t));

        return s_mem_res;
    }

    if (e_addr == MAIN_ADDR)
    {
        addr = get_user_addr(e_user); // 得出当前用户的地址
    }
    else if (e_addr == BACK_ADDR)
    {
        addr = get_user_back_addr(e_user); // 
    }

    addr_offset = ((index - 1) * sizeof(s_mem_t)) + sizeof(s_mem_index_t);

    addr = addr + addr_offset;
    
    *p_e_flash_err = aky_flash_read_bytes(addr, (uint8_t *)&s_mem_res, sizeof(s_mem_t));

    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_mem_res, (uint8_t *)&s_mem_res.check_sum);
    if (s_mem_res.check_sum != get_bytes_checksum((uint8_t *)&s_mem_res, bytes) || *p_e_flash_err == AKY_FLASH_ERR) // 校验出错
    {
        *p_e_flash_err = AKY_FLASH_ERR;
        memset((uint8_t *)&s_mem_res, 0xff, sizeof(s_mem_t));
    }
    else
    {
    }

    return s_mem_res;
}

//擦除所有用户记忆扇区  包括备份区
e_aky_flash_t erase_user_all_mem_pages(e_user_t e_user)
{
    e_aky_flash_t res = AKY_FLASH_OK;
    uint16_t pages = 0;
    uint16_t i = 0;
    uint32_t addr = 0;
    uint32_t addr_back = 0;

    pages = MAX_MEM_ADDR_SIZE / AKY_ONE_SEC_SIZE; // 需要操作的页数

    addr = get_user_addr(e_user);
    addr_back = get_user_back_addr(e_user);

    for (i = 0; i < pages; i++)
    {
        res = aky_flash_erase_pages(addr + (i * AKY_ONE_SEC_SIZE),1);
        if (res != AKY_FLASH_OK)
        {
            return res;
        }
        res = aky_flash_erase_pages(addr_back + (i * AKY_ONE_SEC_SIZE),1);
        if (res != AKY_FLASH_OK)
        {
            return res;
        }
    }
    
    return res;

}

void clr_mem_bank(e_user_t e_user)
{
    s_mem_index_t s_mem_index_temp = { 0 };
    g_s_mem_index = flash_get_mem_index_data(e_user,&g_e_flash_err,MAIN_ADDR);
    s_mem_index_temp = g_s_mem_index;

    g_e_flash_err = erase_user_all_mem_pages(e_user);//先将用户的所有扇区擦除
    g_s_mem_index = get_default_mem_index_data();
    strcpy((char *)&g_s_mem_index.user_name_buf,(const char *)&s_mem_index_temp.user_name_buf);
    g_s_mem_index.gender = s_mem_index_temp.gender; //名字和性别不擦除
    strcpy((char *)&g_s_mem_index.phone_num_buf,(const char *)&s_mem_index_temp.phone_num_buf);
    strcpy((char *)&g_s_mem_index.age_buf,(const char *)&s_mem_index_temp.age_buf);
    g_s_mem_index.flag_is_user_info_valid = s_mem_index_temp.flag_is_user_info_valid;
    flash_save_mem_index_data(g_s_mem_index, e_user,MAIN_ADDR); //
}

void clr_mem_bank_complete(e_user_t e_user)
{
    g_s_mem_index = get_default_mem_index_data();
    g_s_mem_index.e_user = e_user;
    flash_save_mem_index_data(g_s_mem_index, e_user,MAIN_ADDR); //
}

//检查所有记忆的校验值
//return \AKY_FLASH_ERR 校验出错  \AKY_FLASH_OK 所有记忆校验正确
e_aky_flash_t check_mem_checksum(e_user_t e_user,e_addr_t e_addr)
{
    e_aky_flash_t res = AKY_FLASH_OK;
    uint32_t addr = 0;
    uint16_t i;
    s_mem_t s_mem_temp;
    if (e_addr == MAIN_ADDR)
    {
        addr = get_user_addr(e_user); // 得出当前用户的地址
    }
    else if (e_addr == BACK_ADDR)
    {
        addr = get_user_back_addr(e_user); // 
    }

    g_s_mem_index = flash_get_mem_index_data(e_user, &g_e_flash_err,e_addr);
    if (g_e_flash_err == AKY_FLASH_ERR)
    {
        return AKY_FLASH_ERR;
    }
    if (g_s_mem_index.flag_mem_overwrite == 1)
    {
        for (i = 1; i <= g_s_mem_index.mem_set; i++)
        {
            s_mem_temp = flash_get_mem_data(e_user, i, &g_e_flash_err,e_addr);
            if (g_e_flash_err == AKY_FLASH_ERR)
            {
                return AKY_FLASH_ERR;
            }
        }
    }
    else
    {
        for (i = 1; i <= g_s_mem_index.cur_mem_index; i++)
        {
            s_mem_temp = flash_get_mem_data(e_user, i, &g_e_flash_err,e_addr);
            if (g_e_flash_err == AKY_FLASH_ERR)
            {
                return AKY_FLASH_ERR;
            }
        }
    }
    
    return res;
}

//将备份地址的数据写到主地址 或与之相反
//original_addr 原始有效数据的地址
//target_addr 目标地址
//return  操作成功或失败
e_aky_flash_t mem_data_main_back_switch(uint32_t original_addr, uint32_t target_addr)
{
    e_aky_flash_t res = AKY_FLASH_OK;
    uint16_t pages = 0;
    uint16_t i = 0;
    pages = MAX_MEM_ADDR_SIZE / AKY_ONE_SEC_SIZE; // 需要操作的页数

    for (i = 0; i < pages; i+=1)
    {
        res = aky_flash_read_bytes(original_addr + (i * AKY_ONE_SEC_SIZE), (uint8_t *)flash_buf, FLASH_BUF_SIZE); // 读取数据到缓存
        if (res != AKY_FLASH_OK)
        {
            return res;
        }

        res = aky_flash_erase_pages(target_addr + (i * AKY_ONE_SEC_SIZE),1);
        if (res != AKY_FLASH_OK)
        {
            return res;
        }
        res = aky_flash_write_bytes(target_addr + (i * AKY_ONE_SEC_SIZE), (uint8_t *)flash_buf, AKY_ONE_SEC_SIZE);
        if (res != AKY_FLASH_OK)
        {
            return res;
        }
    }
    
    return res;

}

//检查记忆存储
e_aky_flash_t check_mem_bank(e_user_t e_user)
{
    uint16_t i;
    s_mem_index_t s_mem_index_back;
    static uint32_t addr = 0;
    static uint32_t addr_back = 0;

    g_e_flash_err = AKY_FLASH_OK;

    addr = get_user_addr(e_user);
    addr_back = get_user_back_addr(e_user);

    g_s_mem_index = flash_get_mem_index_data(e_user, &g_e_flash_err,MAIN_ADDR);
    if (g_s_mem_index.e_user != e_user)
    {
        g_s_mem_index.e_user = e_user;
        flash_save_mem_index_data(g_s_mem_index, e_user,MAIN_ADDR); // 
    }
    
    s_mem_index_back = flash_get_mem_index_data(e_user, &g_e_flash_err,BACK_ADDR);
    if (s_mem_index_back.e_user != e_user || g_e_flash_err == AKY_FLASH_ERR || check_mem_checksum(e_user,BACK_ADDR) == AKY_FLASH_ERR)//如果备份地址不是当前用户 进行搬运操作
    {
        for (i = 0; i < 3; i++)//最大重试3次
        {
            g_e_flash_err = mem_data_main_back_switch(addr,addr_back);
            g_e_flash_err = check_mem_checksum(e_user,BACK_ADDR);
            if (g_e_flash_err == AKY_FLASH_OK)
            {
                break;
            }
        }
    }
    
    if (g_e_flash_err != AKY_FLASH_OK)
    {
        return g_e_flash_err;
    }

    g_s_mem_index = flash_get_mem_index_data(e_user, &g_e_flash_err,MAIN_ADDR);
    s_mem_index_back = flash_get_mem_index_data(e_user, &g_e_flash_err,BACK_ADDR);
    if (memcmp((uint8_t *)&g_s_mem_index,(uint8_t *)&s_mem_index_back,sizeof(s_mem_index_t)) == 0)//相等则不需要操作
    {
        // if (check_mem_checksum(e_user,MAIN_ADDR) == AKY_FLASH_OK && check_mem_checksum(e_user,BACK_ADDR) == AKY_FLASH_OK)//
        {
            return AKY_FLASH_OK;
        }
    }

    if (check_mem_checksum(e_user,MAIN_ADDR) == AKY_FLASH_OK)//主地址ok则往备份搬
    {
        for (i = 0; i < 3; i++)//最大重试3次
        {
            g_e_flash_err = mem_data_main_back_switch(addr,addr_back);
            g_e_flash_err = check_mem_checksum(e_user,BACK_ADDR);
            if (g_e_flash_err == AKY_FLASH_OK)
            {
                break;
            }
        }
        if (g_e_flash_err != AKY_FLASH_OK)
        {
            return g_e_flash_err;
        }
    }
    else//主地址ng则备份往主地址搬
    {
        if (check_mem_checksum(e_user,BACK_ADDR) == AKY_FLASH_OK)
        {
            for (i = 0; i < 3; i++)//最大重试3次
            {
                g_e_flash_err = mem_data_main_back_switch(addr_back,addr);
                g_e_flash_err = check_mem_checksum(e_user,MAIN_ADDR);
                if (g_e_flash_err == AKY_FLASH_OK)
                {
                    break;
                }
            }
            if (g_e_flash_err != AKY_FLASH_OK)//如果搬运出错则全部清除
            {
                clr_mem_bank(e_user);
                return g_e_flash_err;
            }
        }
        else//备份也出错则全部清除
        {
            clr_mem_bank(e_user);
            return g_e_flash_err;
        }
    }

    return g_e_flash_err;
}





// 当前记忆下标的基础上再插入一笔记忆
e_aky_flash_t insert_one_mem(s_mem_t s_mem, e_user_t e_user)
{
    s_mem_index_t s_mem_index_back;
    uint32_t addr = 0;
    uint32_t addr_back = 0;
    uint16_t i;
    g_e_flash_err = AKY_FLASH_OK;

    addr = get_user_addr(e_user);
    addr_back = get_user_back_addr(e_user);

    {
        g_s_mem_index = flash_get_mem_index_data(e_user, &g_e_flash_err,MAIN_ADDR);
        s_mem_index_back = flash_get_mem_index_data(e_user, &g_e_flash_err,BACK_ADDR);
        if (s_mem_index_back.e_user != e_user)//如果备份地址不是当前用户 进行搬运操作
        {
            for (i = 0; i < 3; i++)//最大重试3次
            {
                g_e_flash_err = mem_data_main_back_switch(addr,addr_back);
                g_e_flash_err = check_mem_checksum(e_user,BACK_ADDR);
                if (g_e_flash_err == AKY_FLASH_OK)
                {
                    break;
                }
            }
        }
        
        if (g_e_flash_err != AKY_FLASH_OK)
        {
            return g_e_flash_err;
        }
    }
    
    g_s_mem_index.cur_mem_index++;//下标自加
    if (g_s_mem_index.cur_mem_index > g_s_mem_index.mem_set)//下标溢出
    {
        g_s_mem_index.flag_mem_overwrite = 1;
        g_s_mem_index.cur_mem_index = 1;
    }
    else
    {
    }

    {
        g_e_flash_err = flash_save_mem_index_data(g_s_mem_index, e_user,MAIN_ADDR);//index下标自加后写回flash
        if (g_e_flash_err != AKY_FLASH_OK)
        {
            return g_e_flash_err;
        }
    }

    g_e_flash_err = flash_save_mem_data(s_mem, e_user, g_s_mem_index.cur_mem_index,MAIN_ADDR);//记忆写入flash
    if (g_e_flash_err != AKY_FLASH_OK)
    {
        return g_e_flash_err;
    }
    g_e_flash_err = check_mem_bank(e_user);
    
    return g_e_flash_err;
}



//保存设定值到flash
void store_set_to_flash(s_set_t s_set)
{
    uint16_t bytes = 0;
    uint16_t i;
    uint8_t *p_u8_buf;
    uint8_t *p_u8_buf_const;
    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_set, (uint8_t *)&s_set.check_sum);
    s_set.check_sum = get_bytes_checksum((uint8_t *)&s_set, bytes);

    memset((uint8_t *)flash_buf, 0xff, FLASH_BUF_SIZE);
    p_u8_buf = (uint8_t *)&s_set;
    p_u8_buf_const = (uint8_t *)&s_set;
    for (i = 0; i < sizeof(s_set_t) * SET_DATA_MAX_SAVE_CNT; i++)//保存次
    {
        flash_buf[i] = *p_u8_buf++;
        if (p_u8_buf >= p_u8_buf_const + sizeof(s_set_t))
        {
            p_u8_buf = (uint8_t *)&s_set;
        }
    }
    

    aky_flash_erase_pages(user_set_addr, 1);
    aky_flash_write_bytes(user_set_addr, (uint8_t *)flash_buf, AKY_ONE_SEC_SIZE);
    aky_flash_erase_pages(user_set_back_addr, 1);
    aky_flash_write_bytes(user_set_back_addr, (uint8_t *)flash_buf, AKY_ONE_SEC_SIZE);
}


//从flash取设定值
s_set_t get_flash_set_data(void)
{
    s_set_t s_set_res = {0};
    uint16_t bytes = 0;
    uint16_t i,j = 0;
    uint16_t ok_mask = 0;

    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_set_res, (uint8_t *)&s_set_res.check_sum);

    ok_mask = 0;
    for (i = 0; i < SET_DATA_MAX_SAVE_CNT; i++)
    {
        g_e_flash_err = aky_flash_read_bytes(user_set_addr + (i * sizeof(s_set_t)), (uint8_t *)&s_set_res, sizeof(s_set_t));
        if (s_set_res.check_sum == get_bytes_checksum((uint8_t *)&s_set_res, bytes) && g_e_flash_err == AKY_FLASH_OK) // 校验通过
        {
            ok_mask |= (0x01 << i);
        }
    }
    if (ok_mask > 0)
    {
        for (i = 0; i < SET_DATA_MAX_SAVE_CNT; i++)
        {
            if ((ok_mask & (0x01 << i)) != (0x01 << i))//如果有错误
            {
                for (j = 0; j < SET_DATA_MAX_SAVE_CNT; j++)
                {
                    if ((ok_mask & (0x01 << j)) == (0x01 << j))//查到正确的则重新写回主地址
                    {
                        g_e_flash_err = aky_flash_read_bytes(user_set_addr + (j * sizeof(s_set_t)), (uint8_t *)&s_set_res, sizeof(s_set_t));
                        if (s_set_res.check_sum == get_bytes_checksum((uint8_t *)&s_set_res, bytes) && g_e_flash_err == AKY_FLASH_OK) // 校验通过
                        {
                            store_set_to_flash(s_set_res); // 写回主地址
                            goto get_set_data_exit;
                        }
                    }            
                }
            }
        }
    }
    

    if (s_set_res.check_sum != get_bytes_checksum((uint8_t *)&s_set_res, bytes) || g_e_flash_err == AKY_FLASH_ERR) // 校验出错
    {
        for (i = 0; i < SET_DATA_MAX_SAVE_CNT; i++)
        {
            g_e_flash_err = aky_flash_read_bytes(user_set_back_addr + (i * sizeof(s_set_t)), (uint8_t *)&s_set_res, sizeof(s_set_t));
            if (s_set_res.check_sum == get_bytes_checksum((uint8_t *)&s_set_res, bytes) && g_e_flash_err == AKY_FLASH_OK) // 校验通过
            {
                break;
            }
        }

        if (s_set_res.check_sum != get_bytes_checksum((uint8_t *)&s_set_res, bytes) || g_e_flash_err == AKY_FLASH_ERR) // 校验出错
        {
            s_set_res = get_default_set_data(); // 读默认
        }
        else
        {
            store_set_to_flash(s_set_res); // 备份写回主地址
        }
    }
    else
    {
    } 
get_set_data_exit:
    return s_set_res;
}

// 通用的存储操作函数 用于小数据存储
// 每次写入 general_save_offset大小的字节  sizeof(s_general_save_t)
// off_set 基于general_save_addr的偏移量
// s_general_save 需要保存的数据
e_aky_flash_t flash_save_general_data(uint16_t off_set, s_general_save_t s_general_save)
{

    uint8_t check_sum_temp = 0;
    e_aky_flash_t res = AKY_FLASH_OK;
    uint16_t i, j = 0;

    uint16_t bytes = 0;
    res = aky_flash_read_bytes(general_save_addr, (uint8_t *)flash_buf, FLASH_BUF_SIZE);
    if (res != AKY_FLASH_OK)
    {
        return res;
    }
    res = aky_flash_erase_pages(general_save_addr, 1);
    if (res != AKY_FLASH_OK)
    {
        return res;
    }

    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_general_save, (uint8_t *)&s_general_save.check_sum);
    s_general_save.check_sum = get_bytes_checksum((uint8_t *)&s_general_save, bytes);

    j = 0;
    for (i = off_set; i < (off_set + sizeof(s_general_save_t)); i++)
    {
        flash_buf[i] = s_general_save.buf[j];
        j++;
    }

    res = aky_flash_write_bytes(general_save_addr, (uint8_t *)flash_buf, AKY_ONE_SEC_SIZE);
    return res;
}

// 取出一组通用数据
// off_set 基于general_save_addr的偏移量
// return  返回取出的数据
s_general_save_t flash_get_general_data(uint16_t off_set)
{
    uint16_t bytes = 0;
    s_general_save_t s_general_save_res = {0};

    g_e_flash_err = aky_flash_read_bytes(general_save_addr + off_set, (uint8_t *)&s_general_save_res, sizeof(s_general_save_t));

    bytes = get_stru_checksum_offset_bytes((uint8_t *)&s_general_save_res, (uint8_t *)&s_general_save_res.check_sum);
    if (s_general_save_res.check_sum != get_bytes_checksum((uint8_t *)&s_general_save_res, bytes) || g_e_flash_err == AKY_FLASH_ERR) // 校验出错
    {
        memset((uint8_t *)&s_general_save_res, 0xff, sizeof(s_general_save_t));
    }
    else
    {
    }

    return s_general_save_res;
}

void flash_test(void)
{
    uint16_t j =0;

    for ( j = 0; j < 99; j++)
    {
        FLASH_Erase(0x7d000);
        for (uint16_t i = 0; i < 4096; i++)
        {
            flash_buf[i] = 0x5a;
        }
        for (uint16_t i = 0; i < 4096; i++)
        {
            if (flash_buf[i] != 0x5a)
            {
                printf("flash_err 11111\n");

                while (1)
                {
                    /* code */
                }
                
            }
            
        }  
	__disable_irq();
        FLASH_Write(0x7d000, (uint32_t *)flash_buf, (4096 / 4));
	__enable_irq();


        for (uint16_t i = 0; i < 4096; i++)
        {
            flash_buf[i] = *(__IO uint8_t*) (0x7d000 + i);
            if (flash_buf[i] != 0x5a)
            {
                printf("flash_err 2222\n");

                while (1)
                {
                    /* code */
                }
                
            }
            
        }    

    }

}


void aky_flash_index_check(e_user_t e_user)
{
    g_e_flash_err = check_mem_bank(e_user);

}

#define WRITE_YEAR_INIT 24
#define WRITE_MONTH_INIT 6
#define WRITE_DAY_INIT 6

#define IS_FAST_WRITE (1) //1 快速写入 写入过程中断电丢失  \0带校验的写入 较慢 但断电会保存
// void write_full_mem_bank(e_user_t e_user)
// {
//     uint16_t mem_cnt = 0;
//     uint16_t i = 0;
//     uint8_t flag_size_add_one = 0;
//     s_bp_t s_aky_bp_temp = {0};
//     uint32_t user_addr = 0;
//     uint16_t index_offset = 0;
//     uint16_t bytes = 0;
//     uint8_t *p_u8_buf;

//     s_time_t s_time_temp = {
//         .year = WRITE_YEAR_INIT,
//         .month = WRITE_MONTH_INIT,
//         .day = WRITE_DAY_INIT,
//     };

//     mem_cnt = 0;
//     clr_mem_bank(e_user);
//     memset((uint8_t *)flash_buf,0x00,MAX_MEM_ADDR_SIZE);

//     while (1)
//     {

    
//         // {
//         //     s_time_temp.day++;
//         //     if (s_time_temp.day > 31 || s_time_temp.day == 0)
//         //     {
//         //         s_time_temp.day = 1;
//         //         s_time_temp.month++;
//         //         if (s_time_temp.month > 12)
//         //         {
//         //             s_time_temp.month = 1;
//         //             s_time_temp.year++;
//         //             if (s_time_temp.year > 99)
//         //             {
//         //                 s_time_temp.year = 1;
//         //             }
//         //         }
//         //     }
//         // }
//         s_time_temp.hour = mem_cnt % 24;
//         s_time_temp.min = mem_cnt % 60;

        
//         g_s_mem.s_time = s_time_temp;


//         g_s_mem.s_left_bp.sys = 50 + mem_cnt % 200;
//         g_s_mem.s_left_bp.dia = 30 + mem_cnt % 170;
//         g_s_mem.s_left_bp.pul = 40 + mem_cnt % 150;

//         g_s_mem.s_right_bp.sys = g_s_mem.s_left_bp.sys + 1;
//         g_s_mem.s_right_bp.dia = g_s_mem.s_left_bp.dia + 1;


//         g_s_mem.s_left_bp_start = g_s_mem.s_left_bp;
//         g_s_mem.s_right_bp_start = g_s_mem.s_right_bp;
//         g_s_mem.s_left_bp_start.sys -= 1;
//         g_s_mem.s_left_bp_start.dia -= 1;
//         g_s_mem.s_left_bp_start.pul -= 1;
//         g_s_mem.s_right_bp_start.sys -= 1;
//         g_s_mem.s_right_bp_start.dia -= 1;


//         g_s_mem.flag_ful_dat = 1;
//         g_s_mem.TrainMode = 5;
//         g_s_mem.TrainPressure = g_s_mem.s_left_bp_start.sys + 50;
//         g_s_mem.s_train_time.min = 50;
//         g_s_mem.s_train_time.secon = 0;
//         printf("mem_cnt = %d\r\n",mem_cnt);
//         if (mem_cnt == 59)
//         {
//             AKY_ASM_NOP();
//             printf("mem_cnt = %d\r\n",mem_cnt);
//         }
//         g_e_flash_err = insert_one_mem(g_s_mem, e_user);

        
//         get_mem_5_days_high(g_e_user);
//         memset((uint8_t *)&g_s_mem,0x00,sizeof(s_mem_t));
//         mem_cnt++;
//         if (mem_cnt >= 200)
//         {
//             break;
//         }
//         // static lv_obj_t *label_write_mem;          //

//         // if (synwit_ui_get_cur_screen_id() == SCREEN003)
//         // {
//         //     label_write_mem = synwit_ui_find_lv_obj(WIDGET_LABEL4);
//         //     lv_label_set_text_fmt(label_write_mem, "写入中..... 第%d组  请稍候",mem_cnt);
//         // }
//     }

//     check_mem_bank(e_user);
// }

void write_full_mem_bank(e_user_t e_user)
{
    uint16_t mem_cnt = 0;
    uint16_t i = 0;
    uint8_t flag_size_add_one = 0;
    s_bp_t s_aky_bp_temp = {0};
    uint32_t user_addr = 0;
    uint16_t index_offset = 0;
    uint16_t bytes = 0;
    uint8_t *p_u8_buf;

    s_time_t s_time_temp = {
        .year = WRITE_YEAR_INIT,
        .month = WRITE_MONTH_INIT,
        .day = WRITE_DAY_INIT,
    };

    mem_cnt = 0;
    clr_mem_bank(e_user);
    memset((uint8_t *)flash_buf,0x00,MAX_MEM_ADDR_SIZE);

    while (1)
    {

    
        {
            s_time_temp.day++;
            if (s_time_temp.day > 31 || s_time_temp.day == 0)
            {
                s_time_temp.day = 1;
                s_time_temp.month++;
                if (s_time_temp.month > 12)
                {
                    s_time_temp.month = 1;
                    s_time_temp.year++;
                    if (s_time_temp.year > 99)
                    {
                        s_time_temp.year = 1;
                    }
                }
            }
        }
        s_time_temp.hour = mem_cnt % 24;
        s_time_temp.min = mem_cnt % 60;

        
        g_s_mem.s_time = s_time_temp;


        g_s_mem.s_left_bp.sys = 50 + mem_cnt % 200;
        g_s_mem.s_left_bp.dia = 30 + mem_cnt % 170;
        g_s_mem.s_left_bp.pul = 40 + mem_cnt % 150;

        g_s_mem.s_right_bp.sys = g_s_mem.s_left_bp.sys + 1;
        g_s_mem.s_right_bp.dia = g_s_mem.s_left_bp.dia + 1;


        g_s_mem.s_left_bp_start = g_s_mem.s_left_bp;
        g_s_mem.s_right_bp_start = g_s_mem.s_right_bp;
        g_s_mem.s_left_bp_start.sys -= 1;
        g_s_mem.s_left_bp_start.dia -= 1;
        g_s_mem.s_left_bp_start.pul -= 1;
        g_s_mem.s_right_bp_start.sys -= 1;
        g_s_mem.s_right_bp_start.dia -= 1;


        g_s_mem.flag_ful_dat = 1;
        g_s_mem.TrainMode = 5;
        g_s_mem.TrainPressure = g_s_mem.s_left_bp_start.sys + 50;
        g_s_mem.s_train_time.min = 50;
        g_s_mem.s_train_time.secon = 0;

        g_e_flash_err = insert_one_mem(g_s_mem, e_user);

        memset((uint8_t *)&g_s_mem,0x00,sizeof(s_mem_t));
        mem_cnt++;
#if 00
if (mem_cnt >= MAX_MEM_SIZE - 1)
{
    break;
}

#else
if (mem_cnt >= MAX_MEM_SIZE)
{
    break;
}


#endif
        // static lv_obj_t *label_write_mem;          //

        // if (synwit_ui_get_cur_screen_id() == SCREEN003)
        // {
        //     label_write_mem = synwit_ui_find_lv_obj(WIDGET_LABEL4);
        //     lv_label_set_text_fmt(label_write_mem, "写入中..... 第%d组  请稍候",mem_cnt);
        // }
    }

    check_mem_bank(e_user);
}



#define FLASH_TEST_ADDR (user_1_addr)
void flash_test_2(void)
{
    uint16_t j =0;
    for ( j = 0; j < 99; j++)
    {
        aky_flash_erase_pages(FLASH_TEST_ADDR,1);
        for (uint16_t i = 0; i < 4096; i++)
        {
            flash_buf[i] = 0x5a;
        }
        for (uint16_t i = 0; i < 4096; i++)
        {
            if (flash_buf[i] != 0x5a)
            {
                printf("flash_err 11111\n");

                while (1)
                {
                    /* code */
                }
                
            }
        }  
        aky_flash_write_bytes(FLASH_TEST_ADDR, (uint8_t *)flash_buf, 4096);

        aky_flash_read_bytes(FLASH_TEST_ADDR,(uint8_t *)flash_buf,4096);
        for (uint16_t i = 0; i < 4096; i++)
        {
            if (flash_buf[i] != 0x5a)
            {
                printf("flash_err 2222\n");

                while (1)
                {
                    /* code */
                }
                
            }
            
        }    

    }


}




